/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦]
 * 
 * https://zhiqim.org/project/zhiqim_framework/zhiqim_httpd.htm
 *
 * Zhiqim Httpd is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.zhiqim.httpd.entities;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;

import org.zhiqim.httpd.HttpContext;
import org.zhiqim.httpd.HttpEntity;
import org.zhiqim.httpd.HttpHeader;
import org.zhiqim.httpd.HttpSender;
import org.zhiqim.httpd.constants.HttpMimeType;
import org.zhiqim.httpd.context.ZmlContextConstants;
import org.zhiqim.kernel.logging.Log;
import org.zhiqim.kernel.logging.LogFactory;
import org.zhiqim.kernel.util.DateTimes;
import org.zhiqim.kernel.util.Files;
import org.zhiqim.kernel.util.Resources;
import org.zhiqim.kernel.util.Streams;
import org.zhiqim.kernel.util.Strings;
import org.zhiqim.kernel.util.Validates;

/**
 * 资源文件处理器，/service/res/*
 * 
 * @version v1.0.0 @author zouzhigang 2014-3-21 新建与整理
 */
public class ServiceResourceEntity implements HttpEntity, ZmlContextConstants
{
    private static final Log log = LogFactory.getLog(ServiceResourceEntity.class);
    
    private final HashMap<String, byte[]> resourceMap = new HashMap<String, byte[]>();
    private final String lastModifiedTime = DateTimes.getDateTimeHttp();
    
    public ServiceResourceEntity()
    {
        try
        {
            //本目录下文件
            List<String> fileNameList = Resources.getResourceFileNameList(ServiceResourceEntity.class, _SERV_RESOURCE_CLASSPATH_);
            
            List<String> imageList = Resources.getResourceFileNameList(ServiceResourceEntity.class, _SERV_RESOURCE_CLASSPATH_ + "image/");
            for (String image : imageList)
            {//image文件
                fileNameList.add("image/"+image);
            }
            
            List<String> fontList = Resources.getResourceFileNameList(ServiceResourceEntity.class, _SERV_RESOURCE_CLASSPATH_ + "font/");
            for (String font : fontList)
            {//font文件
                fileNameList.add("font/"+font);
            }
            
            List<String> extList = Resources.getResourceFileNameList(ServiceResourceEntity.class, _SERV_RESOURCE_CLASSPATH_ + "extend/");
            for (String ext : extList)
            {//extend文件
                fileNameList.add("extend/"+ext);
            }
            
            List<String> swfList = Resources.getResourceFileNameList(ServiceResourceEntity.class, _SERV_RESOURCE_CLASSPATH_ + "swf/");
            for (String swf : swfList)
            {//swf文件
                fileNameList.add("swf/"+swf);
            }
            
            for (String fileName : fileNameList)
            {//对文件缓存
                resourceMap.put(fileName, Streams.getBytesClassPath(ServiceResourceEntity.class, _SERV_RESOURCE_CLASSPATH_ + fileName));
            }
        }
        catch (IOException e)
        {
            log.error("初始化系统资源文件时失败", e);
        }
    }
    
    @Override
    public boolean isMatch(String pathInContext)
    {
        return Validates.isMatch(pathInContext, _PATH_SERVICE_RESOURCE_);
    }
    
    @Override
    public void handle(HttpHeader header, HttpSender sender) throws IOException
    {
        HttpContext context = header.getContext();
        String path = header.getPathInContext();
        String name = Strings.removeStartsWith(path, "/service/res/");
        if (!resourceMap.containsKey(name))
        {//不存在
            sender.sendError(_404_NOT_FOUND_);
            return;
        }
        
        String ifModifiedSince = header.getHeader(_IF_MODIFIED_SINCE_);
        if (ifModifiedSince != null && ifModifiedSince.indexOf(lastModifiedTime) != -1)
        {//如果有要求未修改返回304
            sender.setHeader(_CACHE_CONTROL_, _MAX_AGE_+"="+context.getExpires());
            sender.sendHeader(_304_NOT_MODIFIED_);
            return;
        }
        
        //找到则设置响应属性
        String fileExt = Files.getFileExt(path);
        String mimeType = header.getMimeType();
        if (mimeType == null)
            mimeType = HttpMimeType.getResourceMimeType(fileExt);

        if (mimeType != null)//强制UTF-8
            sender.setContentType(mimeType+"; charset="+_UTF_8_);
        
        //设置响应内容属性
        sender.setCharacterEncoding(_UTF_8_);
        sender.setHeader(_ACCEPT_RANGES_, _BYTES_);
        sender.setHeader(_LAST_MODIFIED_, lastModifiedTime);
        
        if (header.isMethodResponseContent())
        {//GET,POST
            byte[] content = resourceMap.get(name);
            sender.setHeader(_CONTENT_LENGTH_, content.length);
            sender.setHeader(_CACHE_CONTROL_, _MAX_AGE_+"="+context.getExpires());
            sender.write(content);
        }
    }
}
